import { BaseController } from '../BaseController';
import * as CryptoJS from 'crypto-js';
import {ConnPoolInstance} from '../../AppDatabase';

/**
 * 文档：http://developer.huawei.com/consumer/cn/service/hms/catalog/HuaweiJointOperation.html?page=hmssdk_jointOper_api_reference_s1
 * 示例代码：http://developer.huawei.com/consumer/cn/service/hms/catalog/HuaweiJointOperation.html?page=hmssdk_jointOper_payment_sample_code
 */

enum SignType{
    SHA1WithRSA,
    SHA256WithRSA
}

export class huawei extends BaseController {
    // protected SECRET: string = "";
    protected PUBLIC_KEY: string = `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhqRmiRyycGr+G6TBvGWLKB73FqC61utT1FIYm5Axwlpd9ZtlyHYzv/+BL86b4Fus2LrzbeQ8heTaMTY+t251JSIyiOw0dp1AGyUw0A/byQYP+XBNfaZzRGUPwqFn0lIv+e+/Uwobs2M52qYSjzroZGI9/4OPc2sq/bEPXo0DSQCN42TuCrf7bIA5GRUpbpEr4KYMeWMY1zhA9ypL2xxIvpwcWoYRwRTjfLnDUQcxGMxHLsD9AiAy1A2EdXcT0nY6rF1Kfs1EfShaD0UZRxoTVnlpQWkgQKcKdaVoI6IM2+jwZZ3brbKzVIJc5t/VX0hSZBqVufYeUCBpC0W726mbZQIDAQAB`;

    async Start(){
        let postData = this.request.body;

        let keys = Object.keys(postData);
        let sortKeys = keys.sort();

        let toSignStr: string = "";
        for (let i = 1; i < sortKeys.length; i++){
            let key = sortKeys[i];
            let value = postData[key];

            if ("sign" != value && "signType" != value){
                toSignStr += ((i = 0) ? "" : "&");
                toSignStr += (key + "=" + value);
            }        
        }

        let signType = SignType.SHA1WithRSA;
        if (postData.hasOwnProperty("signType") 
            && postData["signType"] == "RSA256")
        {
            signType = SignType.SHA256WithRSA;
        }

        let sign = postData["sign"];
        let verifySign = this.sign(toSignStr, signType, sign);

        await this.saveToDb(postData, verifySign);

        let retJson = {
            result: 0 // 表示成功
        }
        this.response.send(JSON.stringify(retJson));
    }

    private sign(toSignStr: string, signType: SignType, sign: string): Number{
        let signedStr = "";
        if (signType == SignType.SHA1WithRSA){
            signedStr = CryptoJS.SHA1(toSignStr, this.PUBLIC_KEY).toString(CryptoJS.enc.Base64);
        }else if (signType == SignType.SHA256WithRSA){
            signedStr = CryptoJS.SHA256(toSignStr, this.PUBLIC_KEY).toString(CryptoJS.enc.Base64);
        }

        if (signedStr == sign){
            return 1;
        }
        return 0;
    }

    private async saveToDb(postData: any, verifySign: Number){
        let sql = "INSERT INTO huawei_payment_log SET ?";
        let data = {
            result: postData["result"],
            userName: postData["userName"],
            productName: postData["productName"],
            payType: postData["payType"],
            amount: postData["amount"],
            currency: postData["currency"],
            orderId: postData["orderId"],
            notifyTime: postData["notifyTime"],
            requestId: postData["requestId"],
            bankId: postData["bankId"],
            orderTime: postData["orderTime"],
            tradeTime: postData["tradeTime"],
            accessMode: postData["accessMode"],
            spending: postData["spending"],
            extReserved: postData["extReserved"],
            sysReserved: postData["sysReserved"],
            signType: postData["signType"],
            sign: postData["sign"],
            verifySign: verifySign
        };
        
        let ret = await ConnPoolInstance.Insert(sql, data);

        return ret;
    }
}
